/* 
js数据类型：
基本数据类型（简单数据类型）：number 、string 、Boolean、undefined 、null 、symbol、bigint
复杂数据类型（引用数据类型）：array function object date 正则。。。

ts typeScript 它是JavaScript超集 最终编译成js在浏览器当中进行渲染

声明类型变量的格式  关键字可以let  const  var
关键字 变量：数据类型 = 值

关键字 变量：数据类型；
数据类型 = 值

*/

/* 
number


*/
let num: number;
num = 123;
// num = '456';
console.log(num);

let num1: number = 789;
console.log(num1);


let str1: string = 'abc';
let str2: string = 'efd';
let str3: string;
// str3 = str1 + str2;//字符串拼接
str3 = str1 + num1;
console.log(str1, str2, str3);

// 布尔值

let bool1: boolean = true;
console.log(bool1);

// 使用一个关键字声明多个变量

let str4: string, num4: number, bool4: boolean;
str4 = '123';
num4 = 456;
bool4 = false;

console.log(str4, num4, bool4);

// 当你声明完变量类型时候，你的变量的类型就不能变化，不是该类型就会报错

// bool4 = '6456';

// 当变量和赋值是同时进行的，ts就会自动编译变量的数据类型，可以忽略类型声明，但是实际上它声明了类型
let bool3 = false;
bool3 = true;
// bool3 = 123;

console.log(bool3);

// 字面量
let aa: 'zheshu';
aa = 'zheshu';
// aa = "yangyang";
console.log(aa);

// 联合类型
let bb: 'zheshu' | 'yangyang' | 'sizhe' | 123 | false;
// bb = true;
bb = 123;
console.log(bb);

// any unknow
// 有时候你不知道这个变量设计为什么数据类型 但是ts必须规定数据类型，如果不写  当声明变量和赋值在一行时ts默认给设置

let cc: any;
cc = 123;
// cc = '哲书很帅，我们都想你了！！';//any 可以赋值为任意数据类型
let dd: string;
dd = cc;//any 它可以赋值给任意数据类型
console.log(cc);
console.log(dd);

let ee: unknown;
ee = 789;
ee = false;
let ff: string;
// ff = ee;//unknown类型不能赋值给其他类型
let gg: unknown;
gg = ee;
console.log(ee);

// any 和 unknown  都可以赋值为任意数据类型 ，但是any可以赋值给其他数据类型,unknown不能赋值给其他类型，总结 unknown是以中安全的any
// any不建议使用 能使用unknown就不要使用any


// void
// 函数在ts当中如何写
/* function fun(a, b) {
    return a + b;
} */
// 形参  变量
// 函数返回值：当函数内部有return 函数的返回值就是return后面的值，当没有return时，函数的返回值undefined
// 形参需要设计数据类型  函数的返回值需要设计数据类型
// console.log(fun(1, 2));
/* function  函数名（形参1：形参1的数据类型，形参2：形参2的数据类型）:函数返回值的数据类型{
    。。。。
    return xxx
} */
function sum(a: number, b: number): number {
    return a + b;
}
// console.log(sum(1, 2));
// console.log(sum('aa', 2));
function foo(a: number, b: string): string {
    return a + b;
}
console.log(foo(4536, 'bb'));

// void表示没有任何类型，一般用来表示函数的返回值 undefined或者null


function fun1(a: string, b: number): void {
    let c: string = a + b;
    console.log(c);
    // return '4536';
}
console.log(fun1('aa', 2));

/* 
ts进行类型声明，变量类型声明 形参类型声明、函数返回值类型声明
当指定了类型声明之后，ts编辑器就会根据类型声明声明的类型去自动检查是否符合类型，符合执行代码，不符合报错
当指定类型声明之后，该变量之鞥呢存储该类型的值

ts拥有自动的类型判断机制



*/

/* 
数据类型

ts基本的写法
关键字 变量名：变量的数据类型；
变量名 = 变量值；

或者
关键字 变量名：变量的数据类型 = 变量值；

number 、string 、Boolean、字面量、any 、unknown、void  、联合类型
*/

// 对象
/* let obj = {
    name:'tom',
    age:18
}
obj.sex = nv; */
let obj: { name: string, age: number };
obj = {
    name: 'tom',
    age: 18,
}
console.log(obj);
/* 
当对象的数据类型规定完毕后，创建的对象必须严格按照对象规定的数据类型创建，不能多不能少，数据类型也不能不同

有没有需求：对象中的某个属性可能有可能无

*/
// 在规定类型时，在属性名后面加?，表示该属性可选   可有可无
let obj2: { name: string, age: number, sex?: string }

obj2 = {
    name: 'lili',
    age: 18,
    // sex: '男'
}
console.log(obj2);

// 任意往后面加属性名，不知道自己要添加什么属性
let obj3: { name: string, age: number, [propName: string]: unknown };
obj3 = {
    name: 'jenny',
    age: 16,
    sex: '女',
    height: 180
}
obj3.weight = 90;
console.log(obj3);

// array
// string[]  表示当前数组的元素类型都为字符串
let arr: string[];
// arr = ['st','greg','gerg',1513];
arr = ['st', 'greg', 'gerg'];

// number[]表示当前数组的元素类型都为字符串
let arr1: number[];
arr1 = [1, 5, 9]

// Array<number> 表示当前数组元素都为number类型
let arr3: Array<number>;
arr3 = [1, 5, 9];
let arr4: Array<string>;
arr4 = ['few', 'fef', 'geg'];

// 现实当中数组中有可能会存放的数据类型不单一 ['1',111,false]
// 元组 ：元组类型表示的是一个已知元素数量和类型的数组，各个元素的类型不一定相同

let arr5: [string, number, boolean];
arr5 = ['465', 52, false];
console.log(arr5);



// 枚举
// 对数据类型进行一个补充，赋予数据类型一组友好的名字
enum Color {
    Yellow, //0
    Pink, //1
    Blue  // 2
}

let monkey: Color = Color.Pink;


console.log(monkey, Color.Yellow, Color.Blue);//1 0 2

console.log(Color[0], Color[1], Color[2]);


// 手动指定枚举中的值

enum Color1 {
    Yellow = 5,
    Pink,//6
    Blue//7
}

console.log(Color1[5], Color1.Blue, Color1['Pink']);


// 类型联合  表示取值可以是多种类型

let uu: 'zheshu' | 'yangyang' | 'sizhe' | 123;
uu = "zheshu";
uu = 123;
// uu = 4536;
function boo(a: string | number, b: number): void {

    console.log(a, b);
}
boo(85, 45);


// 枚举
enum ObjTest {
    Zheshu,//0
    YangYang,//1
    Sizhe//2
}
console.log(ObjTest['Zheshu']);
console.log(ObjTest[0]);

enum ObjTest1 {
    Zheshu = 6,//0
    YangYang,//1
    Sizhe//2
}
console.log(ObjTest1['Zheshu']);

// number string boolean 字面量 any unknown void object array 元组  enum 联合类型

// 类型断言
// 例如一个函数它的参数x  x的类型可能是数组也可能是string  首先使用了类型联合
function bunnn(x: number | string | false) {
    // 字符串和数字它的用法是不是都不一样  string.length   number.length
    // 按照咱们之前的逻辑字符串怎办  数字怎么办
    // 类型断言
    // 语法
    //方式一： <数据类型>值
    //方式二： 值 as 类型
    // 
    if ((<string>x).length) {
        console.log(111);
        return (<string>x).length;
    } else {
        console.log(222);
        return x.toString().length;
    }
}

console.log(bunnn(false));

// 当使用了ts规定了数据类型之后，你传入的值必须是该类型的值，如果不是就会报错

function bunnn1(x: number | string | false) {
    // 字符串和数字它的用法是不是都不一样  string.length   number.length
    // 按照咱们之前的逻辑字符串怎办  数字怎么办
    // 类型断言:手动指定一个值的类型 
    // 语法
    //方式一： <数据类型>值
    //方式二： 值 as 类型  tsx文件当中只能使用这种  
    // 
    if ((x as string).length) {
        console.log(111);
        return (<string>x).length;
    } else {
        console.log(222);
        return x.toString().length;
    }
}

console.log(bunnn1(false));

// 类型推断 ts中没有明确指定类型时，自动推断出一个数据类型
// 一种：定义变量并且赋值时，推断为对应的数据类型
// 二种：定义变量没有赋值时，推断它的类型为any
let apple = 'pingguo';
// apple = '465';

let appleA;
appleA = 13;
appleA = 'gerg';


// ts中的基本数据类型有哪些：number string Boolean 字面量 any unknown void object array 元组 enum 类型联合 类型断言 类型推断

























